package com.ruoyi.project.applet.util;

import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.collections.FunctorException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

/**
 * @description:
 * @author: Wang.Yide
 * @create: 2022-08-15 09:24
 */
@EnableAsync
@Component
public class PicUtils {

    private static final Logger logger = LoggerFactory.getLogger(PicUtils.class);
    private static int i = 1;
    public static void main(String[] args) throws IOException {
        byte[] bytes = FileUtils.readFileToByteArray(new File("D:\\Tencent\\WeChatFile\\WeChat Files\\wxid_j1iul05vxjdb22\\FileStorage\\File\\2022-08\\2.png"));
        long l = System.currentTimeMillis();
//        bytes = PicUtils.compressPicForScale(bytes, 300, "x");// 图片小于300kb
        System.out.println("耗时"+ (System.currentTimeMillis() - l));
        FileUtils.writeByteArrayToFile(new File("C:\\Users\\w_jin\\Desktop\\file\\11111压缩后.png"), bytes);
    }

//    @Async(value = "asyncServiceExecutor")
    public void writePicForScale(File newFile, String zipSize, String fileName, String zipPath){
        try {
            byte[] bytes = FileUtils.readFileToByteArray(newFile);
            bytes = compressPicForScale(bytes, Long.parseLong(zipSize), fileName);
            FileUtils.writeByteArrayToFile(new File(zipPath), bytes);
        } catch (IOException e) {
            logger.warn("压缩失败:{}", fileName);
            logger.error("压缩失败", e);
        }
    }

    /**
     * 根据指定大小压缩图片
     *
     * @param imageBytes  源图片字节数组
     * @param desFileSize 指定图片大小，单位kb
     * @param imageId     影像编号
     * @return 压缩质量后的图片字节数组
     */
//    @Async(value = "asyncServiceExecutor")
    public byte[] compressPicForScale(byte[] imageBytes, long desFileSize, String imageId) {
        if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
            return imageBytes;
        }
        long srcSize = imageBytes.length;
        double accuracy = getAccuracy(srcSize / 1024);
        try {
            while (imageBytes.length > desFileSize * 1024) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
                Thumbnails.of(inputStream)
                        .scale(accuracy)
                        .outputQuality(accuracy)
                        .toOutputStream(outputStream);
                imageBytes = outputStream.toByteArray();
            }
            logger.info("【图片压缩】imageId={} | 图片原大小={}kb | 压缩后大小={}kb",
                    imageId, srcSize / 1024, imageBytes.length / 1024);
        } catch (Exception e) {
            logger.info("【图片压缩】msg=图片压缩失败：{}!", imageId);
            logger.error("【图片压缩】msg=图片压缩失败!", e);
            throw new FunctorException(e.getMessage());
        }
        return imageBytes;
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < 900) {
            accuracy = 0.85;
        } else if (size < 2047) {
            accuracy = 0.6;
        } else if (size < 3275) {
            accuracy = 0.44;
        } else {
            accuracy = 0.4;
        }
        return accuracy;
    }



}
